################################################################################
# fscheme (C) Copyright funnyos@qq.com 2018
#
# This software is freely distributable under the terms of the MIT 
# License. See the file LICENSE for details.
################################################################################
.data
intro:         .asciiz   " \t   \n  Welcome to fscheme!\n"
comment:       .asciiz   "   ;Welcome to fscheme!\n  Abc"

################################################################################
.text

.globl main

################################################################################
# main()
# entry point
################################################################################
main:
    la   $a0, intro
    jal  eat_whitespace
    move $a0, $v0
    li   $v0, 4  # print_string
    syscall
    la   $a0, comment
    jal  eat_whitespace
    move $a0, $v0
    li   $v0, 4  # print_string
    syscall
    j    exit

################################################################################
# description:
# char* <v0> eat_whitespace(char* <a0>)
# advance the buffer pointer until it reaches the next non-whitespace char
# args:
#   a0: string pointer
# returns:
#   v0: pointer point to the next non-whitespace char
################################################################################
eat_whitespace:
    addi $sp, $sp, -16
    sw   $ra, 12($sp)
    sw   $t2, 8($sp)
    sw   $t1, 4($sp)
    sw   $t0, 0($sp)

    move $t0, $a0
    move $t1, $zero    # make sure that the upper half of $t1 is cleared
eat_whitespace.loop:
    lbu  $t1, 0($t0)   # get the character to be tested
    addi $t0, $t0, 1   # advance the buffer pointer
    beq  $t1, $zero, eat_whitespace.exit
    li   $t2, ' '
    beq  $t1, $t2, eat_whitespace.loop
    li   $t2, '\t'
    beq  $t1, $t2, eat_whitespace.loop
    li   $t2, '\r'
    beq  $t1, $t2, eat_whitespace.loop
    li   $t2, '\n'
    beq  $t1, $t2, eat_whitespace.loop
    li   $t2, ';'
    beq  $t1, $t2, eat_whitespace.eat_comments
    j    eat_whitespace.exit
eat_whitespace.eat_comments:
    move $a0, $t0
    jal  eat_comments
    move $t0, $v0
    j    eat_whitespace.loop
eat_whitespace.exit:
    addi $v0, $t0, -1  # set the return value to the current pointer
    
    lw   $t0, 0($sp)
    lw   $t1, 4($sp)
    lw   $t2, 8($sp)
    lw   $ra, 12($sp)
    addi $sp, $sp, 16
    jr $ra

################################################################################
# description:
# char* <v0> eat_whitespace(char* <a0>)
# advance the buffer pointer until it reaches the next non-whitespace char
# args:
#   a0: string pointer
# returns:
#   v0: pointer point to the next non-whitespace char
################################################################################
eat_comments:
    addi $sp, $sp, -16
    sw   $ra, 12($sp)
    sw   $t2, 8($sp)
    sw   $t1, 4($sp)
    sw   $t0, 0($sp)

    move $t0, $a0
    move $t1, $zero
eat_comments.loop:
    lbu  $t1, 0($t0)   # get the character to be tested
    addi $t0, $t0, 1   # advance the buffer pointer
    beq  $t1, $zero, eat_comments.exit
    li   $t2, '\n'
    beq  $t1, $t2, eat_comments.exit
    j    eat_comments.loop
eat_comments.exit:
    addi $v0, $t0, -1  # set the return value to the current pointer

    lw   $t0, 0($sp)
    lw   $t1, 4($sp)
    lw   $t2, 8($sp)
    lw   $ra, 12($sp)
    addi $sp, $sp, 16
    jr $ra
################################################################################
# exit
################################################################################
exit:
    li   $v0, 17  # exit
    syscall
